import { SelfPromise } from "@/common/GlobalType";
import { UploadRequestOptions } from "element-plus";
import SparkMD5 from "spark-md5";

let chunkSize = 5 * 1024 * 1024

export const calculateFileMD5 = (file: File): SelfPromise => {
    return new Promise((resolve, reject) => {
        const spark = new SparkMD5.ArrayBuffer();
        const fileReader = new FileReader();
        fileReader.onload = (e: any) => {
            spark.append(e.target.result);
            resolve([undefined, spark.end()]);
        };
        fileReader.onerror = (e) => {
            resolve([{ e }, undefined]);
        };
        fileReader.readAsArrayBuffer(file);
    });
}

export const sliceFile = (file: File): Blob[] => {
    const chunks = [];
    let start = 0;
    let end;
    while (start < file.size) {
        end = Math.min(start + chunkSize, file.size);
        chunks.push(file.slice(start, end));
        start = end;
    }
    return chunks;
}

export const multipleRequest = (file: File, fileMd5: string): SelfPromise => {
    return new Promise(async (resolve) => {
        let fileArr = sliceFile(file);
        const len = fileArr.length;
        while (fileArr.length) {
            const item = fileArr.shift() as Blob;
            const index = len - fileArr.length;
            let data = new FormData();
            data.append("totalNumber", len + '');
            data.append("chunkSize", chunkSize + '');
            data.append("chunkNumber", index + '');
            data.append("md5", fileMd5);
            data.append("file", new File([item], file.name));
            const temp = ((index + 1) / len).toFixed(2);
            await CommonService.uploadImage(data);
        }
        resolve([undefined, true]);
    });
}


export const sliceUpload = async (obj: UploadRequestOptions) => {
    const { file, onProgress, onSuccess, onError } = obj;
    const [fileMd5Err, fileMd5] = await calculateFileMD5(file);
    if (fileMd5Err) return [fileMd5Err, undefined]
    await multipleRequest(file, fileMd5);
}